from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection
from decimal import Decimal
import json
from django import http
from django.utils import timezone
from django.db import transaction



import logging
logger = logging.getLogger('django')





from meiduo_mail.utils.views import LoginRequiredMixin,LoginRequiredView
from users.models import Address
from goods.models import SKU
from .models import OrderInfo,OrderGoods
from meiduo_mail.utils.response_code import  RETCODE


# Create your views here.

class OrderSettlementView(LoginRequiredMixin, View):
    def get(self,request):
        user = request.user
        address_qs = Address.objects.filter(user=user,is_deleted=False)
        # 创建rdis连接
        # 获取hash和set
        # 定义新字典用来包装要勾选的id和count
        # 将勾选的商品对应的sku模型全部查出来
        # 响应
        redis_conn = get_redis_connection('carts')
        redis_carts = redis_conn.hgetall('cart_%s' % user.id)
        selected_ids = redis_conn.smembers('selected_%s' % user.id)
        cart_dict = {}
        for sku_id_bytes in selected_ids:
            cart_dict[int(sku_id_bytes)] = int(redis_carts[sku_id_bytes])

        sku_qs = SKU.objects.filter(id__in=cart_dict.keys())
        total_count = 0
        total_amount = Decimal('0.00')

        for sku in sku_qs:
            sku.count = cart_dict[sku.id]
            sku.amount = sku.count * sku.price
            total_count += sku.count
            total_amount += sku.amount
        freight = Decimal('10.00')  # 运费
        context = {
            "addresses": address_qs,  # 当前登录用户的所有收货地址
                'skus': sku_qs,  # 购物车中勾选的所有商品数据
                'total_count': total_count,  # 要购买的商品总数量
                'total_amount': total_amount,  # 商品总金额
                'freight': freight,  # 运费
                'payment_amount': total_amount + freight,  # 实付款
            }
        return render(request, 'place_order.html', context)


class OrderCommitView(LoginRequiredView):

     def post(self,request):
        #  接受数据
        #  校验
        #  新增订单基本信息
        #     过去redis中的购物车数据
        #  只留下购物车商品的id和count
        # 判断库存是否充足
        # 修改sku库存和销量
        # 修改spu库存和销量
        # 新增n个订单中商品记录

        json_dict = json.loads(request.body.decode())
        address_id = json_dict.get('address_id')
        pay_method = json_dict.get('pay_method')
        if all([address_id,pay_method]) is False:
            return http.HttpResponseForbidden('缺少必传参数')
        user = request.user

        try:
            address = Address.objects.get(id=address_id,user=user)
        except Address.DoesNotExist:
            return http.HttpResponseForbidden('address_id错误')

        try:
            pay_method = int(pay_method)
            if pay_method not in [OrderInfo.PAY_METHODS_ENUM['CASH'], OrderInfo.PAY_METHODS_ENUM['ALIPAY']]:
                return http.HttpResponseForbidden('支付方式有误')
        except Exception as e:
            logger.error(e)
            return http.HttpResponseForbidden('支付方式有误')
        #  新增订单基本信息
        #     过去redis中的购物车数据
        #  只留下购物车商品的id和count
        # 判断库存是否充足
        # 修改sku库存和销量
        # 修改spu库存和销量
        # 新增n个订单中商品记录
        # user = request.user


        # 拼接订单号
        order_id = timezone.now().strftime(('%Y%m%d%H%M%S')) + '%09d' % user.id
        # 订单状态
        status = (OrderInfo.ORDER_STATUS_ENUM['UNPAID']
                    if pay_method ==OrderInfo.PAY_METHODS_ENUM['ALIPAY']
                    else OrderInfo.ORDER_STATUS_ENUM['UNSEND'])

        with transaction.atomic():
            save_point = transaction.savepoint()
            try:
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    pay_method=pay_method,
                    status=status,
                    total_amount=Decimal('0.00'),
                    total_count=0,
                    freight=Decimal(10.00)
                )

                redis_conn = get_redis_connection('carts')
                redis_carts = redis_conn.hgetall('cart_%s' % user.id)
                selected_ids = redis_conn.smembers('selected_%s' % user.id)
                cart_dict = {}
                for sku_id_bytes in selected_ids:
                    cart_dict[int(sku_id_bytes)] = int(redis_carts[sku_id_bytes])

                for sku_id in cart_dict:

                    while True:
                        sku = SKU.objects.get(id=sku_id)
                        buy_count = cart_dict[sku_id]
                        origin_stock = sku.stock
                        origin_sales = sku.sales


                        if buy_count > origin_stock:

                            transaction.savepoint_rollback(save_point)

                            return http.JsonResponse({'code': RETCODE.STOCKERR, 'errmsg': '库存不足'})

                        new_stock = origin_stock - buy_count
                        new_sales = origin_sales + buy_count
                        # sku.stock = new_stock
                        # sku.sales = new_sales
                        # sku.save()

                        result = SKU.objects.filter(id=sku_id,stock=origin_stock).update(stock=new_stock, sales=new_sales)
                        if result == 0:
                            continue
                        spu = sku.spu
                        spu.sales += buy_count
                        spu.save()

                        OrderGoods.objects.create(
                            order=order,
                            sku=sku,
                            count=buy_count,
                            price=sku.price
                        )
                        order.total_count += buy_count
                        order.total_amount += (sku.price * buy_count)
                        break
                order.total_amount += order.freight
                order.save()
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_point)
                return http.JsonResponse({'code': RETCODE.STOCKERR, 'errmsg': '下单失败'})
            else:
                transaction.savepoint_commit(save_point)

        pl = redis_conn.pipeline()
        pl.hdel('cart_%s' % user.id, *selected_ids)
        pl.delete('selected_%s' % user.id)
        pl.execute()


        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '提交订单成功', 'order_id': order_id})


class OrderSuccessView(LoginRequiredView):

    def get(self,request):
        query_dict = request.GET
        payment_amount = query_dict.get('payment_amount')
        order_id = query_dict.get('order_id')
        pay_method= query_dict.get('pay_method')

        try:
            OrderInfo.objects.get(order_id=order_id, total_amount=payment_amount,pay_method=pay_method,
                                  user=request.user)
        except OrderInfo.DoesNotExist:
            return http.HttpResponseForbidden('orderInfo错误')

        context = {
            'payment_amount': payment_amount,
            'order_id': order_id,
            'pay_method': pay_method
        }

        return render(request, 'order_success.html', context)





